Most users of the VideoToolbox, especially GDOpenWindow, will want to read this document. This document contains my (slightly abbreviated) correspondence with with Don Moccia at Apple Developer Services about how to get CopyBits to faithfully copy the pixels from one image to another. Don illuminated several obscure but important points about how color tables and palettes affect CopyBits. (Apple Developer Support only accepts questions from certified Apple Partners. APDA can give you application information. Basically you have to have produced a commercial product for the Mac, e.g. the ISR Video Attenuator, and pay $1,500/year.)
I want to use CopyBits addOver mode to quickly add two 8-bit GWorlds. That is,
I want to add the index stored in each pixel of the first GWorld to the index
in the corresponding pixel of the second GWorld. No matter what I try, CopyBits
seems to add the colors, not the indexes.
Both GWorlds and the current device have the same gray color table. Both
GWorlds have palettes based on that gray color table, with every entry marked
pmExplicit. As suggested by Inside Mac VI, page 20-17, I set bit 14 of the
ctFlags field of the color table. I tried lots of other variants as well, but I
never managed to get simple addition of the indexs.
Is it possible to get CopyBits to just add the raw pixels?
Denis Pelli
Professor of Neuroscience
Syracuse University
BACKGROUND
I have 8 Macs of various vintages (II to 6100/60). I publish on info-mac a
VideoToolbox of C source code for accurate synthesis of visual images for
vision research on Macs that is used by hundreds of my colleagues. I'm using
System 7 Pro and Metrowerks CodeWarrior C.
---------------------------
Denis,
Since this seems to be your first technical question as an Apple Partner, I
wish I could give you a more helpful answer. As you've found out, the
arithmetic transfer modes work in color space, not index space. The reason is
that the Macintosh color table is easily and frequently modified. Because of
this color space based operations provide a more reliable and consistent
approach to color management. This is documented in "Inside Macintosh Imaging
with QuickDraw,", p.4-38.
>> As suggested by Inside Mac VI, page 20-17, I set bit 14 of the ctFlags field
of the color table.
FYI - This technique is usually used when coordinating a GWorld with a window
that has an attached palette.
If you want to give us some idea of what you are trying to accomplish, perhaps
we can come up with an alternative approach. For example, if CopyBits speed is
an issue, you might be able to use the techniques in the QuickDraw Tech Note
"QD 21 - Time and Space and CopyBits" on any Reference Edition Developer CD,
e.g. September `94.
Just send a link to my attention if you think I can be of any help.
Regards,
Don Moccia
Apple Developer Support
Reference Number 117781
-----------------------------------------
Dear Don
thanks for the quick reply. I'm disappointed to hear that the addOver mode won't work directly on the indexs, but I can live with that, as I've written my own code.
However, could you clarify for me what I have to do to get slavish copying of pixels, without translation, using srcCopy mode? I think I've read all the relevant manuals several times, but I never quite get it, in large part because the manuals discuss CopyBits in one place and the Palette manager in another, leaving it quite unclear what the implications of the Palettes are for the use of CopyBits. I want to copy between GWorlds, or from them to color windows. I'm doing fancy image processing on the GWorlds, using my own code. The images are always grayscale. I don't want any color translation, partly for reasons of speed (Yes, thanks, I have read "Of time space and copybits"--it was helpful), and partly because I have gone to a lot of trouble to calculate these images exactly right, and I don't want them messed with, just copied, quickly. Is it enough for the color tables (source and current device) to have the same ctSeed?
(In our typical setup we have several monitors, and use one to show the processed images. This monitor is given a special gray color table. In fact, though it's not directly relevant to our discussion, I go behind QuickDraw's back and do driver level calls to set the CLUT to take full advantage of a custom harware scheme that combines the RGB outputs electrically to create a more-than-8-bit precision grayscale signal that drives the monitor. See Pelli, D. G. and Zhang, L. (1991) Accurate control of contrast on microcomputer displays. Vision Research, 31, 1337-1350. As a result, I really don't care what color table I officially load into the device, anything to make CopyBits happy. At present I'm using the default grayscale color table.)
I normally add a palette to all my GWorlds with all entries marked as explicit, so that I can use pmForeColor. I presume that this will affect CopyBits srcCopy, but it's not clear to me how. (Should I also be setting pmTolerant, in addition to pmExplicit?). It is utterly unclear to me whether adding a palette to the DESTINATION makes any difference. What exactly is the effect of setting bit 14 of the ctFlags field of the SOURCE pixmap's color table? (You said, "FYI - This technique is usually used when coordinating a GWorld with a window that has an attached palette." Could you spell out for me how this bit affects CopyBits? The manual is enigmatic.) What is the effect of setting bit 14 of the ctFlags field of the DESTINATION pixmap's color table? None? What is the effect of setting bit 14 of the ctFlags field of the CURRENT DEVICE's pixmap's color table? (As far as I know there is no way to associate a Palette with a device.)
As you see, I've got things working, but I'm unclear on what things affect CopyBits srcCopy, and how, so I'm not confident that they will continue working. Again, my question is, how do palettes affect CopyBits srcCopy? I'd be grateful for any light you can shed on this.
regards
denis
Denis Pelli
Syracuse University
p.s. Will the New Inside Mac "Advanced Color Imaging" explain how palettes affect CopyBits? Any idea when it will be available?
--------------------------------------
Hi Denis,
I apologize for the cut-and-paste style, but you've asked a lot of questions
and I want to make sure I address them all. I've tried to group related
questions together, I hope it's not too much of a mishmash.
>> ...what I have to do to get slavish copying of pixels, without translation,
using srcCopy mode?
>> Is it enough for the color tables (source and current device) to have the
same ctSeed?
QuickDraw relies on ctSeed to tell it if color tables are identical or not. If
the two color tables have the same ctSeed, QuickDraw assumes they are the same.
Naturally, you can get odd results if the color tables in fact differ. To get
your slavish copying you need to ensure that the color tables are identical,
which brings us to the next section...
>> I normally add a palette to all my GWorlds with all entries marked as
explicit, so that I can use pmForeColor.
From one of our Macintosh Palette Manager Q&As on the Reference Edition
Developer CDs: "The Macintosh Palette Manager doesn't work on offscreen
environments the way you'd expect. Unlike color windows, SetPalette will not
change the offscreen's color table; rather it just allows you to use
PmForeColor and PMBackColor to set the current drawing color in that
environment. To change the offscreen's color table you'll need to convert the
palette to a color table and then set the resulting color table to the off
screen. Calling Palette2CTab will do the converting for you. To get around
having to use palettes to define the current drawing color in the off screen,
you can always use Index2Color and then RGBForeColor to get the color to be set
for drawing."
So you'll need to convert your palette to a color table and then use that color
table to create the GWorld. The QuickDraw Snippet "Out of This GWorld" on Tool
Chest Edition Developer CDs, e.g. November `94, shows this technique in the
createGWorld() routine in the out.c file.
>> (Should I also be setting pmTolerant, in addition to pmExplicit?).
Although it doesn't apply in this case, you need to set pmTolerant to zero if
you want to guarantee that the precise color is present.
>> What exactly is the effect of setting bit 14 of the ctFlags field of the SOURCE pixmap's color table?
>> Could you spell out for me how this bit affects CopyBits?
A clearer explanation of this is in the QuickDraw Tech Note "QD 13 - Principia
Off-Screen Graphics Environments." If bit 14 of ctFlags is set, " then the
value field of each ColorSpec record in the ctTable array is used by _CopyBits
as an index into the color palette that's attached to the destination window,
and the rgb field is ignored."
>> What is the effect of setting bit 14 of the ctFlags field of the DESTINATION pixmap's color table?
>> What is the effect of setting bit 14 of the ctFlags field of the CURRENT DEVICE's pixmap's color table?
There are no effects documented and, as far as I know, no effects in real life
either.
>> ...the manuals discuss CopyBits in one place and the Palette manager in another, leaving it quite unclear what the implications of the Palettes are for the use of CopyBits.
>> Will "Advanced Color Imaging" explain how palettes affect CopyBits? Any idea when it will be available?
"Advanced Color Imaging" is very late. Early versions of some of the chapters
may appear on the December Developer CD. I won't guess about the actual
publishing date.
I don't think the Palette Manager chapter has undergone much of a review yet,
so it is probably pretty similar to Inside Mac VI. I definitely feel that the
relationship of palettes to GWorlds and CopyBits needs clarification. I will be
reviewing the chapter and will keep your comments in mind. If you read the
chapter and want to make comments, please feel free to send them to me and I
will give them to the editor.
Let me know if I left anything out. Also, your article sounds interesting. Do
you have an electronic copy you can send?
Regards,
Don Moccia
Apple Developer Support
Reference Number 117781
-----------------------------------------
Dear Don
many thanks. Your reply was thorough and very helpful. However, I'm still puzzled by bit 14 of ctFlags.
As you requested, I'm enclosing a draft of my paper. It's a WriteNow 4 document. I'd also like to mail you a reprint of the final published version. Could you give me your mailing address? (This is just for your interest. It's irrelevant to my question.)
Here's the bit that puzzled me. You said,
"A clearer explanation of this is in the QuickDraw Tech Note "QD 13 - Principia Off-Screen Graphics Environments." If bit 14 of ctFlags is set, " then the value field of each ColorSpec record in the ctTable array is used by _CopyBits as an index into the color palette that's attached to the destination window, and the rgb field is ignored."
That doesn't make sense to me. CopyBits only receives a destination PixMap, so how does it know which window is relevant in order to find "the color palette that's attached to the destination window"? Sounds like magic. QD13 goes on to say that this is "explained in IM VI-20-17". So I re-read that too. I'm still baffled. I don't understand what it's saying and I don't understand what CopyBits does. CopyBits has no information about windows, and palettes are only connected to windows, not pixmaps or devices, so I don't see how copybits can use a palette, since I can't think of any way for it to find the palette. (Well, I can think of ways, but they seem unreasonable: e.g. finding the frontmost window that overlaps the global coordinates of the pixmap. Or perhaps CopyBits recovers the destination window by comparing its destination pixmap with every possible window's pixmap.)
Can you clarify this for me? Bit 14 of ctFlags still seems very relevant to solving my problems, but I can't seem to get consistent behavior out of it, probably because I don't understand what it's supposed to do. I can't imagine how palettes affect copybits, since by rights copybits has no way of knowing which palettes would be relevant.
Thanks again for the help on this. I feel close to understanding something that's been mysterious for a long time.
regards
denis pelli
-----------------------------------------
Hi Denis,
Thanks for the article. We (I) can get so involved in Apple technology that it
becomes easy to lose sight of what's going on outside the company. I guess
that's a variation of Apple's NIH (not invented here) syndrome. My mailing
address is:
Don Moccia
Apple Computer, Inc.
MS 303-2T
1 Infinite Loop
Cupertino, CA 95014
Now to ctFlags' bit 14.
Restrict yourself to thinking of it in the case of a CopyBits from an offscreen
graphics environment, be it PixMap or GWorld, to a window. This is the only
case where it comes into play. As we've said, when you set bit 14 in the
offscreen's color table, you are telling the system to consider the value field
of each color table entry as an index into the destination color table. The
actual RGB values are ignored. For example, if a pixel in the source (indexed
color) PixMap has a value of 9, and the ninth entry in the source color table
contains 6 in its value field, that pixel will be mapped to the sixth entry in
the palette attached to the destination window. (I'm assuming srcCopy.) I think
you probably already understood this. By the way, you can try unsetting bit 14
in the "Out of This GWorld" snippet I mention previously to see its effect.
So how is the connection made? QuickDraw knows it is drawing to a window by
looking at the baseAddr field of the PixMap. A window's baseAddr is always the
same as the main screen's PixMap. A color window has a CGrafPort. A CGrafPort
has the grafVars field which contains the handle to an attached palette (if
any). This last fact is documented somewhat obscurely in Inside Mac V, e.g. p.
V-113. I hope we'll describe this connection more clearly in the new Palette
Manager chapter. Another article that might help fill in the pieces is
"Multiple Screens Revealed" in develop Issue #10. It doesn't talk about bit 14,
but it gives some insight into how QuickDraw handles windows and offscreens.
So this is how the connection is made. Remember, QuickDraw was developed over
ten years ago, so calls such as CopyBits know more about the System than they
would in a modern object-oriented environment. Things will evolve however.
Anyway, let me know if there are still missing pieces.
Regards,
Don Moccia
Apple Developer Support
Reference Number 117781
---------------------------
Dear Don
Click! I think I've got it now. However, I'm curious. You implied that the bit 14 mechanism only works if the destination is a window. I would like to use it when the destination is a GWorld too. Is there some logical reason for CopyBits to prevent this? Why not do it whenever bit 14 of the source is set and grafVars of the destination is not NULL? (The consistent treatment of GWorlds and windows is one of the nicest features of 32-bit quickdraw, seems a shame to break it for no reason.)
Thanks again. The reprint will go out tomorrow morning (actually 2, one showing some neat research on human letter recognition that we did using QuickDraw).
regards
denis
Denis Pelli
Syracuse University
p.s. Vis a vis documentation. The documentation of NewGWorld and UpdateGWorld are a touch brief. If they are ever revised it would be nice if they spelled out the fact that when the boundsRect is interpreted as being in global coordinates the GWorld's portRect always has its upper left corner set to local coordinate (0,0). I thought I'd found a bug, until I carefully re-read the documentation. (The documentation of boundsRect for UpdateGWorld is copied word for word from NewGWorld, including the references to NewGWorld where it obviously means UpdateGWorld.)
------------
p.p.s. wait. I still don't see how CopyBits knows which window, since it only has the pixmap. Oh, I see it now; and this answers my question about GWorlds. CopyBits must compare the handle of the pixmap with the portPixMap field of EVERY window until it finds the right window. It can't do this for GWorlds because there's no globally available list of GWorlds.
Is that right?
regards
denis
---------------
denis,
I agree 100% with your wish to use palettes and bit 14 seamlessly across
GWorlds and windows. I wasn't around when the design decisions were made, so I
don't know if it was a "time to market" issue or if there were major technical
obstacles.
One of the big problems for a company, when you are committed to compatibility
and have a large installed base of varying machines, is it is hard to make
changes without breaking someone's app. Even if you make the change
successfully, it requires a large SQA effort to ship the product. I wouldn't be
surprised if it came down to someone thinking, perhaps correctly, that it was
too great a risk given the deadlines and resources available at the time.
The major priorities in QuickDraw, not counting GX, are finishing the port to
PowerMac and correcting bugs (either old or created by the port). So I can't
say if the Palette Manager will be broadened in the future or if it will be
replaced by a new paradigm. If I hear anything of interest (that I can talk
about), I'll make sure you hear about it.
Again, thanks for the papers. Perhaps, I'll be asking you some questions!